//
//  String+QRCode.swift
//  CLExtension
//
//  Created by CharlieLiao on 2017/8/22.
//  Copyright © 2017年 Charlie. All rights reserved.
//

import UIKit

public extension String
{
    /**
     生成二维码
     - parameter size:            大小         (大小为300)
     - parameter logo:            图标
     - parameter color:           二维码颜色       黑
     - parameter bgColor:         二维码背景颜色   白
     - parameter radius:          圆角           5
     - parameter borderLineWidth: 线宽           1.5
     - parameter borderLineColor: 线颜色
     - parameter boderWidth:      带宽           8
     - parameter borderColor:     带颜色
     - returns: 自定义二维码
     */
    func generateQRCode(size: CGFloat = 300, logo: UIImage? = nil, color: UIColor = UIColor.black, bgColor: UIColor = UIColor.white, radius: CGFloat = 5, borderLineWidth: CGFloat = 1.5, borderLineColor: UIColor = UIColor.gray, boderWidth: CGFloat = 8, borderColor: UIColor = UIColor.white) -> UIImage
    {
        if let ciImage = generateCIImage(size: size, color: color, bgColor: bgColor) {
            let image = UIImage(ciImage: ciImage)
            
            let logoBorderImage: UIImage?
            let logoWidth = image.size.width/4
            let logoFrame = CGRect(x: (image.size.width - logoWidth) / 2, y: (image.size.width - logoWidth) / 2, width: logoWidth, height: logoWidth)
            
            // logo搞一下边框
            if let QRCodeLogo = logo {
                //边框
                let logoBorderLineImage = QRCodeLogo.roundRect(size: logoFrame.size, radius: radius, borderWidth: borderLineWidth, borderColor: borderLineColor)
                
                logoBorderImage = logoBorderLineImage.roundRect(size: logoFrame.size, radius: radius, borderWidth: boderWidth, borderColor: borderColor)
            } else {
                logoBorderImage = nil
            }
            
            // 重新画一下，直接用ciImage会导致不能转换成data
            UIGraphicsBeginImageContextWithOptions(image.size, false, UIScreen.main.scale)
            image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
            // 绘制logo
            logoBorderImage?.draw(in: logoFrame)
            let QRCodeImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            if QRCodeImage != nil {
                return QRCodeImage!
            }
        }
        return UIImage(graphics: bgColor, size: CGSize(width: size, height: size))
    }
    
    /**
     生成CIImage
     - parameter size:    大小
     - parameter color:   颜色
     - parameter bgColor: 背景颜色
     - returns: CIImage
     */
    func generateCIImage(size: CGFloat, color: UIColor, bgColor: UIColor) -> CIImage?
    {
        //2.二维码滤镜
        let contentData = self.data(using: String.Encoding.utf8)
        if let fileter = CIFilter(name: "CIQRCodeGenerator") {
            fileter.setValue(contentData, forKey: "inputMessage")
            fileter.setValue("H", forKey: "inputCorrectionLevel")
            if let ciImage = fileter.outputImage {
                
                //3.颜色滤镜
                if let colorFilter = CIFilter(name: "CIFalseColor") {
                    colorFilter.setValue(ciImage, forKey: "inputImage")
                    // 二维码颜色
                    colorFilter.setValue(CIColor(cgColor: color.cgColor), forKey: "inputColor0")
                    // 背景色
                    colorFilter.setValue(CIColor(cgColor: bgColor.cgColor), forKey: "inputColor1")
                    
                    //4.生成处理
                    if let outImage = colorFilter.outputImage {
                        let scale = size / outImage.extent.size.width;
                        let transform = CGAffineTransform(scaleX: scale, y: scale)
                        return outImage.transformed(by: transform)
                    }
                }
            }
        }
        return nil
    }
}


extension UIImage
{
    /**
     识别图片二维码
     - returns: 二维码内容
     */
    public func recognizeQRCode() -> String?
    {
        if let cgImg = cgImage {
            if let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyHigh]) {
                if let feature = detector.features(in: CIImage(cgImage: cgImg)).first as? CIQRCodeFeature {
                    return feature.messageString
                }
            }
        }
        return nil
    }
}
